package gamemodels;

import gamecomponents.graphic.BlitData;
import gamecomponents.graphic.Blitable;
import gamecomponents.graphic.TextureHelper;
import gamecomponents.menu.MenuButton;
import gamecomponents.menu.MenuImage;
import gamecomponents.settings.GameSettings;
import input.InputManager;

import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.List;
import java.util.Observable;

import com.threed.jpct.SimpleVector;

/**
 * The Main Menu
 * @author Team Deer
 *
 */
public class MainMenuModel extends Observable implements IGameModel {

	private static MainMenuModel singletonInstance;
	private IGameModel nextModel;

	private final SimpleVector screenSize;

	private final MenuImage backgroundImage;

	private final MenuButton newGameButton;
	private final MenuButton leaderboardButton;
	private final MenuButton exitButton;

	private boolean requestExit;

	private final List<Blitable> components;

	// Constructor and singleton getter
	
	/**
	 * Constructs a new Main Menu model
	 */
	private MainMenuModel() {

		this.screenSize = GameSettings.SCREEN_SIZE;

		this.requestExit = false;

		this.components = new LinkedList<Blitable>();

		this.backgroundImage = new MenuImage(
				TextureHelper
						.loadTexture("Content\\Sprites\\Menu\\menubackground.png"),
				0, 0, (int) this.screenSize.x, (int) this.screenSize.y, 255);
		this.components.add(this.backgroundImage);

		/*
		 * Add a semitrans background to menu... MenuImage backgroundShadowImage
		 * = new MenuImage( TextureHelper.getSemiTransparentTexture(), (int)
		 * (this.screenSize.x / 10), (int) (this.screenSize.y / 2) + 35, 500,
		 * 275, 255); this.components.add(backgroundShadowImage);
		 */

		this.newGameButton = new MenuButton(
				TextureHelper
						.loadTexture("Content\\Sprites\\Menu\\newGameActive.png"),
				TextureHelper
						.loadTexture("Content\\Sprites\\Menu\\newGameInactive.png"),
				(int) (this.screenSize.x / 8),
				(int) (this.screenSize.y / 2 + 75), 325, 51, 255);
		this.components.add(this.newGameButton);

		this.leaderboardButton = new MenuButton(
				TextureHelper
						.loadTexture("Content\\Sprites\\Menu\\leaderboardActive.png"),
				TextureHelper
						.loadTexture("Content\\Sprites\\Menu\\leaderboardInactive.png"),
				(int) this.screenSize.x / 8, (int) this.screenSize.y / 2 + 150,
				410, 48, 255);
		this.components.add(this.leaderboardButton);

		this.exitButton = new MenuButton(
				TextureHelper
						.loadTexture("Content\\Sprites\\Menu\\exitActive.png"),
				TextureHelper
						.loadTexture("Content\\Sprites\\Menu\\exitInactive.png"),
				(int) this.screenSize.x / 8, (int) this.screenSize.y / 2 + 225,
				124, 49, 255);
		this.components.add(this.exitButton);
		super.setChanged();
	}

	/**
	 * 
	 * @return the singleton instance
	 */
	public static MainMenuModel getInstance() {
		if (singletonInstance == null) {
			singletonInstance = new MainMenuModel();
		}
		return singletonInstance;
	}

	// Update
	
	@Override
	public void reset() {
		this.requestExit = false;
		this.nextModel = null;
	}
	
	@Override
	public boolean isRunning() {
		return !this.requestExit;
	}

	@Override
	public void update(final InputManager inputManager) {
		if (inputManager.getKeyboardState().isKeyPressed(KeyEvent.VK_ESCAPE) &&
				inputManager.getKeyboardState().getPreviousKeyboardState().isKeyUp(KeyEvent.VK_ESCAPE)) {
			this.requestExit = true;
		}

		this.updateButtons(inputManager);
		if (this.buttonsHasChanged()) {
			super.setChanged();
		}

		super.notifyObservers();
	}

	/**
	 * Updates the button in the main menu model
	 * @param inputManager the inputmanager
	 */
	private void updateButtons(final InputManager inputManager) {
		this.newGameButton.update(inputManager);
		this.leaderboardButton.update(inputManager);
		this.exitButton.update(inputManager);
		if (inputManager.mouseIsClicked()) {
			if (this.newGameButton.pointIsOver(inputManager.getMousePosition())) {
				this.changeModel(NewGameMenuModel.getInstance());
			}
			if (this.leaderboardButton.pointIsOver(inputManager
					.getMousePosition())) {
				this.changeModel(LeaderBoardMenuModel.getInstance());
			}
			if (this.exitButton.pointIsOver(inputManager.getMousePosition())) {
				this.requestExit = true;
			}
		}
	}

	private boolean buttonsHasChanged() {
		return this.newGameButton.hasChanged()
				|| this.leaderboardButton.hasChanged()
				|| this.exitButton.hasChanged();
	}

	private void changeModel(final IGameModel model) {
		this.nextModel = model;
	}

	@Override
	public IGameModel getNextModel() {
		return this.nextModel;
	}

	// Viewhelp
	
	@Override
	public List<BlitData> getBlitData() {
	
		final List<BlitData> list = new LinkedList<BlitData>();
	
		for (final Blitable data : this.components) {
			list.add(new BlitData(
					data.getTexture(), // texture
					0 /* srcX */, 0 /* srcY */, data.getPosition().x /* destX */,
					data.getPosition().y /* destY */,
					data.getSrcWidth() /* sourceWidth */,
					data.getSrcHeight() /* sourceHeight */,
					data.getWidth() /* destWidth */,
					data.getHeight() /* destHeight */, 255 /* transValue */,
					false /* additive */, null)); /* addColor */
		}
	
		return list;
	}

}
